package cn.outsourcing.supermarket.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;

/**
 * 请求处理
 *
 * @author gzkemays
 * @since 2021/10/21 11:49
 */
public class YzjHttp {
  /** edge 的用户模拟头 */
  public static final String EDGE_USER_AGENT =
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64";
  /** 自动重定向请求调用，默认为 true */
  private static final RequestConfig REQUEST_CONFIG =
      RequestConfig.custom().setRedirectsEnabled(false).build();
  /** 请求客户端 */
  private CloseableHttpClient client;
  /** 请求网关时间 */
  private int socketTimeOut;
  /** 请求时间 */
  private int connectTimeOut;
  /** 请求链接时间 */
  private int connectRequestTimeOut;
  /** 请求配置 */
  RequestConfig requestConfig = getRequestConfig();

  {
    try {
      getIgnoreSslClient();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * 基本超时配置
   *
   * @return {@link RequestConfig} 请求配置
   */
  public static RequestConfig getRequestConfig() {
    return RequestConfig.custom()
        .setSocketTimeout(20000)
        .setConnectTimeout(20000)
        .setConnectionRequestTimeout(20000)
        .build();
  }

  public static YzjHttp goHttp() {
    return new YzjHttp();
  }

  /**
   * 采取默认配置的请求
   *
   * @param url 请求地址
   * @return 请求返回结果
   */
  public static String goGet(String url) {
    return goHttp().get(url);
  }

  /**
   * 返回结果为 JsonObject
   *
   * @param url 请求地址
   * @return 请求返回结果
   */
  public static JSONObject goGetToJsonObj(String url) {
    String result = goHttp().get(url);
    if (JsonUtils.isJson(result)) {
      return JSONObject.parseObject(result);
    }
    throw new IllegalArgumentException("返回结果不是 JSON 格式");
  }

  /**
   * 发送无参 get 请求
   *
   * @param url 请求地址
   * @return 返回 result 结果
   */
  public String get(String url) {
    try {
      CloseableHttpResponse response;
      response = client.execute(htpGet(url));
      return EntityUtils.toString(response.getEntity(), "UTF-8");
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 构造 get 请求
   *
   * @param url 请求地址
   * @return 返回 HttpGet 构造结果
   */
  public HttpGet htpGet(String url) {
    HttpGet httpGet = new HttpGet(url);
    httpGet.setHeader(HTTP.USER_AGENT, EDGE_USER_AGENT);
    httpGet.setConfig(requestConfig);
    return httpGet;
  }

  public YzjHttp socketTimeOut(int time) {
    this.requestConfig = RequestConfig.copy(requestConfig).setSocketTimeout(time).build();
    return this;
  }

  public YzjHttp connectTimeOut(int time) {
    this.requestConfig = RequestConfig.copy(requestConfig).setConnectTimeout(time).build();
    return this;
  }

  public YzjHttp connectRequestTimeOut(int time) {
    this.requestConfig =
        RequestConfig.copy(requestConfig).setConnectionRequestTimeout(time).build();
    return this;
  }

  /** 忽略 SSL 证书 */
  private void getIgnoreSslClient() throws Exception {
    SSLContext sslContext =
        SSLContexts.custom().loadTrustMaterial(null, (x509Certificates, s) -> true).build();
    // 创建httpClient
    this.client =
        HttpClients.custom()
            .setSSLContext(sslContext)
            .setSSLHostnameVerifier(new NoopHostnameVerifier())
            .build();
  }
}
